'use strict';
const Controller = require('egg').Controller;
const bcrypt = require('bcryptjs');
const qiniu = require('qiniu');
const qn_key = require('../../config/keys').qn;
class UserController extends Controller {


    // yes
    //用户注册 
    /** * 传入3个参数 username email password*/
    async register() {
        const { ctx, app } = this;
        //校验字段
        let { username, email, password } = ctx.request.body;
        let validateResult = await ctx.validate('register', { username, email, password });
        if (!validateResult) { return };
        let res = await ctx.service.user.getUserByUsername(username);
        if (res) {
            ctx.body = { code: '-1', msg: '用户名已存在' }
        } else {
            const newUser = {
                username: username,
                password: password,
                email: email,
                avatar: 'http://s2.lixiade.top/defaultLogo.png',
                createTime: new Date()
            };
            //密码加密 
            let salt = bcrypt.genSaltSync(1);
            newUser.password = bcrypt.hashSync(newUser.password, salt);
            let addUser = await ctx.service.user.register(newUser);
            // ctx.body = newUser;
            if (addUser.affectedRows === 1) {
                //注册成功后应直接登录成功,返回token 
                let auth = app.jwt.sign({
                    uid: addUser.insertId,
                    username: newUser.username,
                    //需要存储的 token 数据 
                    email: newUser.email,
                    introduction: '',
                    avatar: newUser.avatar,
                    createDate: newUser.createTime
                }, app.config.jwt.secret, {
                    expiresIn: "86400s"
                        //过期时间1天 
                });
                ctx.body = {
                    code: '0',
                    data: auth
                }
            } else {
                ctx.body = {
                    code: '-1',
                    msg: "注册失败请稍后再试"
                }
            }
        }
    };

    // yes
    //用户登录 
    /** * 传入2个参数 username password */
    async login() {
        const { ctx, app } = this;
        //获取用户名密码 
        let { username, password } = ctx.request.body;
        let validateResult = await ctx.validate('login', { username, password });
        if (!validateResult) { return }; //查询用户信息 
        let res = await ctx.service.user.getUserByUsername(username);
        // ctx.body = res;
        if (res) { //比较密码是否正确 
            if (bcrypt.compareSync(password, res.password)) {
                let auth = app.jwt.sign({
                        uid: res.uid,
                        username: res.username, //需要存储的 token 数据 
                        email: res.email,
                        introduction: res.userIntroduction,
                        avatar: res.userAvatar,
                        createDate: res.userCreateTime
                    },
                    app.config.jwt.secret, {
                        expiresIn: "86400s" //过期时间1天 
                    });
                ctx.body = {
                    code: '0',
                    data: auth
                }
            } else {
                ctx.body = { code: '-1', msg: '密码错误' }
            }
        } else {
            ctx.body = { code: '-1', msg: '用户不存在' };
        }
    };


    // yes
    // 获取用户信息
    /**
     * 根据用户id获取用户基本信息
     */
    async getUserInfo() {
        const { ctx } = this;
        const { myid, peopleid } = ctx.query;
        // ctx.body = ctx.query;
        let res = await ctx.service.user.getUserHomeById(myid, peopleid);
        if (res) {
            ctx.body = {
                code: '0',
                data: res[0]
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: "获取信息失败"
            }
        }
    };
    //yes
    //获取七牛云空间上传图片的token 
    async getToken() {
        const { ctx } = this;
        //需要填写你的 Access Key 和 Secret Key 
        let accessKey = qn_key.ak;
        let secretKey = qn_key.sk;
        let mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
        //要上传的空间 
        let bucket = 'lixiade';
        let options = {
            scope: bucket,
            returnBody: '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"fileUrl":"s2.lixiade.top/$(key)"}'
        }; //获取上传token 
        let putPolicy = new qiniu.rs.PutPolicy(options);
        let uploadToken = putPolicy.uploadToken(mac);
        ctx.body = { code: '0', data: uploadToken }
    };
    //yes
    //获取所有分类信息 
    async getCategoryList() {
        const { ctx } = this;
        let categoryList = await ctx.service.user.getCategoryList();
        if (categoryList) {
            ctx.body = { code: '0', data: categoryList }
        } else {
            ctx.body = { code: '-1', msg: '获取失败' }
        }
    };
    //yes
    //写文章 
    /** * 传入5个参数 userid screenshot title content categoryid */
    async write() {
        const { ctx } = this;
        //用户id、屏幕快照、标题、文章内容、分类 
        let {
            userid,
            screenshot,
            title,
            content,
            categoryid
        } = ctx.request.body;
        let validateResult = await ctx.validate('write', { title, categoryid });
        if (!validateResult) { return };
        //正则删除所有html标签 
        let reg = /(<[^>]+>)/ig;
        let deleteTag = content.replace(reg, '');
        //截取前100个字得到文章摘要 
        let summaryInfo = deleteTag.substring(0, 100);
        const newArticle = {
            userid: userid,
            screenshot: screenshot,
            title: title,
            summaryInfo: summaryInfo,
            content: content,
            categoryId: categoryid,
            postTime: new Date()
        };
        let res = await ctx.service.user.write(newArticle); // 
        ctx.body = res;
        if (res) {
            ctx.body = {
                code: '0',
                msg: '添加成功'
            }
        } else {
            ctx.status = 400;
            ctx.body = {
                code: '-1',
                msg: '提交失败'
            }
        }
    };
    //yes
    //分页获取该用户的文章数据 
    /** * 传入3个参数 uid size currentsize */
    async getArticlesByPage() {
        const { ctx } = this;
        // 查询的用户id, 需要获取的条数， 已获取的条数
        let { myid, peopleid, size, currentsize } = ctx.query;
        //query的传参都是string类型的，需要转换为number类型 
        size = parseInt(size);
        currentsize = parseInt(currentsize);
        let validateResult = await ctx.validate('getArticle', { peopleid, size, currentsize })
        if (!validateResult) {
            return
        };
        let params = {
            myid: myid,
            peopleid: peopleid,
            size: size,
            currentsize: currentsize
        };
        let res = await ctx.service.user.getArticlesByPage(params);
        if (res) {
            let arr = res.map(item => {
                const { categoryId, categoryName, categoryTitle, uid, username, userAvatar, userIntroduction, ...others } = item
                return {...others,
                    categoryInfo: { categoryId, categoryName, categoryTitle },
                    userInfo: {
                        uid,
                        username,
                        userAvatar,
                        userIntroduction
                    }
                }
            })
            ctx.body = {
                code: '0',
                data: arr
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '查询失败'
            }
        }
    };
    //yes
    //获取单篇文章信息 
    /**
     *  传入2个参数 articleid uid 
     * 
     */
    async getArticlesById() {
        const { ctx } = this;
        const { articleid, uid } = ctx.query;
        const data = {
            articleid: articleid,
            uid: uid
        };
        // ctx.body = data;
        let res = await ctx.service.user.getArticlesById(data);
        if (res) {
            // ctx.body = res;
            let arr = res.map(item => {
                const { categoryid, categorytitle, categoryname, userid, username, email, avatar, ...others } = item;
                return {
                    ...others,
                    categoryinfo: { categoryid, categorytitle, categoryname, },
                    userinfo: { userid, username, email, avatar }
                }
            })
            ctx.body = {
                code: '0',
                data: arr[0]
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '获取文章失败'
            }
        }
    };
    //yes
    //点击关注用户 
    /** * 传入2个参数 followerid(关注者id) followeeid(被关注者id) */
    async followUser() {
        const { ctx } = this;
        const { followerid, followeeid } = ctx.query;
        const followUser = {
            followerid: parseInt(followerid),
            followeeid: parseInt(followeeid),
            createat: new Date()
        };
        //关注前，先判断 被关注者id是否存在 
        let isExistUser = await ctx.service.user.getUserById(followUser.followeeid);
        if (isExistUser) {
            let res = await ctx.service.user.followUser(followUser);
            if (res) {
                ctx.body = {
                    code: '0',
                    msg: '关注成功'
                }
            } else {
                ctx.body = {
                    code: '-1',
                    msg: '关注失败'
                }
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '关注的用户不存在'
            }
        }
    };
    //yes
    //点击取消关注用户 
    /** * 传入2个参数 followerid(关注者id) followeeid(被关注者id) */
    async unfollowUser() {
        const { ctx } = this;
        let { followerid, followeeid } = ctx.query;
        const unfollowUser = {
            followerid: parseInt(followerid),
            followeeid: parseInt(followeeid)
        };
        let res = await ctx.service.user.unfollowUser(unfollowUser);
        if (res) {
            ctx.body = {
                code: '0',
                msg: '取消关注成功'
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '取消失败'
            }
        }
    };

    //yes
    //获取用户关注信息(粉丝数，关注数) 
    /** * 传入1个参数 uid */
    async getFollowInfo() {
        const { ctx } = this;
        let { uid } = ctx.query;
        uid = parseInt(uid);
        // 获取该用户关注的用户数量
        let FollowerCount = await ctx.service.user.getFollowerCount(uid);
        // 获取该用户被关注的数量
        let FollowingCount = await ctx.service.user.getFollowingCount(uid);
        if (FollowerCount || FollowingCount) {
            ctx.body = {
                code: '0',
                data: {
                    followerNum: FollowerCount.length,
                    followeeNum: FollowingCount.length
                }
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '获取失败'
            }
        }
    };
    //yes
    //分页查看用户关注了哪些人
    /** * 传入4个参数 myid peopleid size currentsize */
    async getFollowings() {
        const { ctx } = this;
        let { myid, peopleid, size, currentsize } = ctx.query;
        let res = await ctx.service.user.getFollowings(myid, peopleid, size, currentsize);
        if (res) {
            ctx.body = {
                code: '0',
                data: res
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '查询失败'
            }
        }
    };
    //yes
    //分页查看用户粉丝 
    /** * 传入4个参数 myid peopleid size currentsize */
    async getFollowers() {
        const { ctx } = this;
        let { myid, peopleid, size, currentsize } = ctx.query;
        let res = await ctx.service.user.getFollowers(myid, peopleid, size, currentsize);
        if (res) {
            ctx.body = {
                code: '0',
                data: res
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '查询失败'
            }
        }
    };
    //yes
    //用户根据文章id点赞文章 
    /** * 传入2个参数 uid articleid */
    async likeArticle() {
        const { ctx } = this;
        let { uid, articleid } = ctx.query;
        uid = parseInt(uid);
        articleid = parseInt(articleid);
        let date = new Date();
        let res = ctx.service.user.likeArticle(uid, articleid, date);
        if (res) {
            ctx.body = {
                code: '0',
                msg: '点赞成功'
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '点赞失败'
            }
        }
    };
    //yes
    //用户根据文章id取消点赞文章 
    /** * 传入2个参数 uid articleid */
    async unlikeArticle() {
        const { ctx } = this;
        let { uid, articleid } = ctx.query;
        uid = parseInt(uid);
        articleid = parseInt(articleid);
        //先判断文章id是否存在 
        let isExistArticle = ctx.service.user.getArticlesById(articleid);
        if (isExistArticle) {
            let res = ctx.service.user.unlikeArticle(uid,
                articleid);
            if (res) {
                ctx.body = {
                    code: '0',
                    msg: '取消点赞成功'
                }
            } else {
                ctx.body = {
                    code: '-1',
                    msg: '取消点赞失败'
                }
            }

        } else {
            ctx.body = {
                code: '-1',
                msg: '文章不存在'
            }
        }
    };
    //yes
    //首页根据文章分类来分页获取文章列表 (规定每次请求发送20条数据) 
    /** * 传入3个参数 categoryid
    currentsize  uid*/
    async getListByCategory() {
        const { ctx } = this;
        let { categoryid, currentsize, uid, size } = ctx.query;

        let res = await ctx.service.user.getListByCategory(categoryid, currentsize, uid, size);
        ctx.body = res;
        if (res) {
            let arr = res.map(item => {
                const { categoryId, categoryName, categoryTitle, uid, username, userAvatar, ...others } = item
                return {...others,
                    categoryInfo: { categoryId, categoryName, categoryTitle },
                    userInfo: {
                        uid,
                        username,
                        userAvatar
                    }
                }
            })
            ctx.body = {
                code: '0',
                data: arr
            }
        } else {
            ctx.status = 404;
            ctx.body = {
                code: '-1',
                msg: '请求失败'
            }
        }
    };
    //yes
    //根据id获取用户文章被点赞总数和被浏览总数 
    /** * 传入1个参数 uid */
    async getLikedAndViewdCount() {
        const { ctx } = this;
        let { uid } = ctx.query;
        uid = parseInt(uid);
        let res = await ctx.service.user.getLikedAndViewdCount(uid);
        if (res) {
            ctx.body = {
                code: '0',
                data: res[0]
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '获取失败'
            }
        }

    };
    //yes
    //根据用户id获取收藏夹列表,并判断该文章是否已存在于这些收藏夹内 
    /** * 传入2个参数 uid articleid */
    async getFavoriteList() {
        const { ctx } = this;
        let { uid, articleid } = ctx.query;
        uid = parseInt(uid);
        articleid = parseInt(articleid);
        let res = await ctx.service.user.getFavoriteList(uid, articleid);
        if (res) {
            ctx.body = {
                code: '0',
                data: res
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '获取失败'
            }
        }
    };
    //yes
    //根据用户id，将文章收藏在该收藏夹中 
    /** * 传入3个参数 uid articleid favoriteid */
    async collection() {
        const { ctx } = this;
        let { uid, articleid, favoriteid } = ctx.query;
        uid = parseInt(uid);
        articleid = parseInt(articleid);
        favoriteid = parseInt(favoriteid);
        let res = await ctx.service.user.collection(uid, articleid, favoriteid);
        if (res) {
            ctx.body = {
                code: '0',
                msg: '收藏成功',
                isIn: res[0].isIn
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '收藏失败'
            }
        }
    };
    //yes
    //根据用户id，取消文章在此收藏夹的收录
    /** 
     * 
     * 传入3个参数 uid articleid favoriteid 
     * 
     */
    async cancelCollection() {
        const { ctx } = this;
        let { uid, articleid, favoriteid } = ctx.query;
        uid = parseInt(uid);
        articleid = parseInt(articleid);
        favoriteid = parseInt(favoriteid);
        let res = await
        ctx.service.user.cancelCollection(uid, articleid, favoriteid);
        if (res) {
            ctx.body = {
                code: '0',
                msg: '取消成功',
                isIn: res[0].isIn
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '取消失败'
            }
        }
    };
    //yes
    //根据用户id新建收藏夹,并收藏当前文章到该收藏夹 
    /**
     *  传入3个参数 uid articleid favoritename
     * 
     */
    async addFolder() {
        const { ctx } = this;
        const { uid, articleid, foldername, favoritesImage } = ctx.request.body;

        let res = await ctx.service.user.addFolder(uid, articleid, foldername, favoritesImage);
        if (res) {
            ctx.body = {
                code: '0',
                msg: '新建成功'
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '新建收藏夹失败'
            }
        }
    }


    //根据用户id 收藏夹id删除收藏夹 
    /** * 传入个参数 uid favoriteid */
    async deleteFavorites() {
        const { ctx } = this;
        let { uid, favoriteid } = ctx.query;
        uid = parseInt(uid);
        favoriteid = parseInt(favoriteid);
        let res = await ctx.service.user.deleteFavorites(uid, favoriteid);
        if (res) {
            ctx.body = {
                code: '0',
                msg: '删除成功'
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '删除失败'
            }
        }
    };
    //yes
    //根据用户id获取收藏夹列表和每个列表内的收藏数量 
    /** * 传入1个参数 uid */
    async getFavoriteListInfo() {
        const { ctx } = this;
        const { uid } = ctx.query;
        let res = await ctx.service.user.getFavoriteListInfo(uid);
        ctx.body = res;
        if (res) {
            ctx.body = {
                code: '0',
                data: res
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: "获取失败"
            }
        }
    };
    //yes
    // 根据收藏夹id获取收藏的文章
    async getArticlesByFavoriteId() {
        const { ctx } = this;
        const { favoriteid, myid } = ctx.query;
        //先判断该收藏夹是否存在
        let exist = await ctx.service.user.checkFavoriteId(favoriteid);
        // ctx.body = exist;
        if (exist) {
            // ctx.body = exist;
            // 开始获取数据
            let res = await ctx.service.user.getArticlesByFavoriteId(favoriteid, myid);
            // ctx.body = res;
            if (res) {
                ctx.body = {
                    code: '0',
                    data: {
                        "articles": res,
                        "favoriteinfo": exist
                    }
                }
            } else {
                ctx.body = {
                    code: '-1',
                    msg: '获取失败'
                }
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '该收藏夹不存在'
            }
        }
    };

    // 更新用户头像
    async updateAvatar() {
        const { ctx, app } = this;
        const { avatar, uid } = ctx.request.body;
        const res = await ctx.service.user.updateAvatar(avatar, uid);
        if (res) {
            const authorization = ctx.request.header.authorization;
            const token = authorization.split(' ')[1];
            const { username, email, introduction, createDate } = app.jwt.verify(token)
            let auth = app.jwt.sign({
                uid: uid,
                username: username,
                //需要存储的 token 数据 
                email: email,
                introduction: introduction,
                avatar: avatar,
                createDate: createDate
            }, app.config.jwt.secret, {
                expiresIn: "86400s"
                    //过期时间1天 
            });
            ctx.body = {
                code: '0',
                data: auth
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: "更新失败"
            }
        }
    };

    // 更新用户其余信息
    async updateUserInfo() {
        const { ctx, app } = this;
        const { uid, username, email, introduction, avatar, createDate } = ctx.request.body;
        let validateResult = await ctx.validate('userInfo', { username, email, introduction });
        if (!validateResult) { return };
        const res = await ctx.service.user.updateUserInfo(uid, username, email, introduction);
        if (res) {
            let auth = app.jwt.sign({
                uid: uid,
                username: username,
                //需要存储的 token 数据 
                email: email,
                introduction: introduction,
                avatar: avatar,
                createDate: createDate
            }, app.config.jwt.secret, {
                expiresIn: "86400s"
                    //过期时间1天 
            });
            ctx.body = {
                code: '0',
                data: auth
            }
        } else {
            ctx.body = {
                code: '0',
                msg: '更新失败'
            }
        }
    };

    //根据文章id获取所有评论及回复信息
    /**
     * 传入一个参数 articleid
     */
    async getAllComments() {
        const { ctx } = this;
        const { articleid } = ctx.query;
        const res = await ctx.service.user.getAllComments(articleid);
        if (res) {
            let count;
            if (res.length > 0) {
                count = res[0].articleComments
            } else {
                count = 0
            }
            let newArr = res.reduce(({ m, replys }, { comments_id, user_id, username, email, userAvatar, comments_content, comments_date, hasreply, ...others }) => {
                let comment = m[comments_id]
                if (!comment) {
                    comment = m[comments_id] = { comments_id, user_id, username, email, userAvatar, comments_content, comments_date, replys: [] };
                    replys.push(comment)
                }
                if (hasreply) {
                    comment.replys.push({...others })
                }
                return { m, replys }
            }, { m: {}, replys: [] }).replys

            ctx.body = {
                code: '0',
                data: {
                    count: count,
                    comments: newArr
                }
            };
        } else {
            ctx.body = {
                code: '-1',
                msg: '获取失败'
            }
        }
    }


    // 添加回复
    async sendReply() {
        const { ctx } = this;
        const { comments_id, myid, to_userid, reply_content } = ctx.request.body;

        const date = new Date();
        const res = await ctx.service.user.sendReply(comments_id, myid, to_userid, reply_content, date)
        if (res) {
            ctx.body = {
                code: '0',
                msg: "回复成功"
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: "回复失败"
            }
        }
    }

    // 添加评论
    async sendComment() {
        const { ctx } = this;
        const { myid, articleid, content } = ctx.request.body;
        // ctx.body = ctx.request.body;
        const date = new Date();
        const res = await ctx.service.user.sendComment(myid, articleid, content, date);
        if (res) {
            ctx.body = {
                code: '0',
                msg: "评论成功"
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: "评论失败"
            }
        }
    }

    // 根据关键字分页搜索文章列表
    // 还要判断当前用户是否点赞这些文章
    async getArticlesByKeyword() {
        const { ctx } = this;
        const { keyword, currentsize, size, uid } = ctx.query;
        // ctx.body = [keyword, currentsize, size, uid];
        const res = await ctx.service.user.getArticlesByKeyword(keyword, currentsize, size, uid);
        if (res) {
            ctx.body = {
                code: '0',
                data: res
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: '查询失败'
            }
        }
    }

    // 获取热门作者,前5位
    async getHotAuthor() {
        const { ctx } = this;
        const res = await ctx.service.user.getHotAuthor();
        if (res) {
            ctx.body = {
                code: '0',
                data: res
            }
        } else {
            ctx.body = {
                code: '-1',
                msg: "获取失败"
            }
        }
    }

}
module.exports = UserController;